home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / TECHNICA / COMPUTER / H254.ZIP / IRITSM3S.ZIP / CAGD_LIB / CBZR_PWR.C < prev    next >
C/C++ Source or Header  |  1991-05-18  |  5KB  |  142 lines

  1. /******************************************************************************
  2. * CBzr_Pwr.c - Bezier to pawer basis conversion.                  *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Jun. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #ifdef __MSDOS__
  8. #include <stdlib.h>
  9. #endif /* __MSDOS__ */
  10.  
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "cagd_loc.h"
  15.  
  16. static CagdRType BinomCoef(int n, int i);
  17.  
  18. /******************************************************************************
  19. * Convert the given curve from Bezier basis function to Power basis.          *
  20. * Using:                                      *
  21. *                                          *
  22. *      n                                      *
  23. *      __                                      *
  24. *  n      \    j-i n    j   j                              *
  25. * B (t) = /  (-1)  ( ) ( ) t                              *
  26. *  i      --        j   i                              *
  27. *     j=i                                      *
  28. *                         n-i                  *
  29. * Which can be derived by expanding the (1-t)    term in bezier basis          *
  30. * function definition as:                              *
  31. *                                            *
  32. *        n-i                                    *
  33. *           __                                    *
  34. *      n-i  \  n-i      j                              *
  35. * (1-t)   = / (   ) (-t)    using binomial expansion.              *
  36. *        --  j                                  *
  37. *       j=0                                      *
  38. *                                                                 *
  39. * This routine simply take the weight of each Bezier basis function B(t) and  *
  40. * spread it into the different power basis t^j function scaled by:          *
  41. *                                                                 *
  42. *    j-i n    j                                  *
  43. *   (-1)   ( ) ( )                                                           *
  44. *           j   i                                                   *
  45. ******************************************************************************/
  46. CagdCrvStruct *CnvrtBezier2PowerCrv(CagdCrvStruct *Crv)
  47. {
  48.     CagdBType
  49.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  50.     int i, j, l,
  51.     n = Crv -> Length,
  52.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  53.     CagdRType *PwrP, *BzrP;
  54.     CagdCrvStruct
  55.     *NewCrv = CagdCrvNew(CAGD_CPOWER_TYPE, Crv -> PType, n);
  56.  
  57.     NewCrv -> Order = n;
  58.  
  59.     for (l = IsNotRational; l <= MaxCoord; l++) {
  60.     PwrP = NewCrv -> Points[l];
  61.     BzrP = Crv -> Points[l];
  62.     ZAP_MEM(PwrP, sizeof(CagdRType) * n);
  63.  
  64.     for (i = 0; i < n; i++) {
  65.         for (j = i; j < n; j++) {
  66.         PwrP[j] += BzrP[i] * BinomCoef(n, j) * BinomCoef(j, i) *
  67.                         (((j - i) & 0x01) ? -1 : 1);
  68.         }
  69.     }
  70.     }
  71.  
  72.     return NewCrv;
  73. }
  74.  
  75. /******************************************************************************
  76. * Convert the given curve from Power basis function to Bezier basis.          *
  77. * Using:                                      *
  78. *                                          *
  79. *      n    j                                      *
  80. *      __  ( )                                      *
  81. *   i  \    i     n                                  *
  82. *  t = /  ----- B (t)                                  *
  83. *      --   n     j                                  *
  84. *      j=i ( )                                      *
  85. *        i                                      *
  86. *                                                                 *
  87. * This routine simply take the weight of each Power basis function t^i and    *
  88. * spread it into the different basis basis function B(t) scaled by:          *
  89. *                                                                 *
  90. *     j   / n                                      *
  91. *    ( ) / ( )                                                           *
  92. *     i /   i                                                       *
  93. ******************************************************************************/
  94. CagdCrvStruct *CnvrtPower2BezierCrv(CagdCrvStruct *Crv)
  95. {
  96.     CagdBType
  97.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  98.     int i, j, l,
  99.     n = Crv -> Length,
  100.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  101.     CagdRType *PwrP, *BzrP;
  102.     CagdCrvStruct
  103.     *NewCrv = BzrCrvNew(n, Crv -> PType);
  104.  
  105.     for (l = IsNotRational; l <= MaxCoord; l++) {
  106.     PwrP = Crv -> Points[l];
  107.     BzrP = NewCrv -> Points[l];
  108.     ZAP_MEM(BzrP, sizeof(CagdRType) * n);
  109.  
  110.     for (i = 0; i < n; i++) {
  111.         for (j = i; j < n; j++) {
  112.         BzrP[j] += PwrP[i] * BinomCoef(j, i) / BinomCoef(n, i);
  113.         }
  114.     }
  115.     }
  116.  
  117.     return NewCrv;
  118. }
  119.  
  120. /******************************************************************************
  121. * Evaluate the following:                              *
  122. *             n         n!                          *
  123. *            ( ) = -------------                      *
  124. *             i    i! * (n - i)!                      *
  125. ******************************************************************************/
  126. static CagdRType BinomCoef(int n, int i)
  127. {
  128.     int j;
  129.     CagdRType c = 1.0;
  130.  
  131.     if ((n >> 1) > i) {                /* i is less than half of n: */
  132.     for (j = n - i + 1; j <= n; j++) c *= j;
  133.     for (j = 2; j <= i; j++) c /= j;
  134.     }
  135.     else {
  136.     for (j = i + 1; j <= n; j++) c *= j;
  137.     for (j = 2; j <= n - i; j++) c /= j;
  138.     }
  139.  
  140.     return c;
  141. }
  142.